<!DOCTYPE html>
<html>
<!--
Copyright 2009 The Closure Library Authors. All Rights Reserved.

Use of this source code is governed by the Apache License, Version 2.0.
See the COPYING file for details.
-->
<!--
-->
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Closure Unit Tests - goog.events.FileDropHandler</title>
  <script src="../base.js"></script>
<script>
  goog.require('goog.events.FileDropHandler');
  goog.require('goog.events.FileDropHandler.EventType');
  goog.require('goog.events');
  goog.require('goog.events.BrowserEvent');
  goog.require('goog.events.EventTarget');
  goog.require('goog.events.EventType');
  goog.require('goog.testing.jsunit');
</script>
</head>
<body>

<script>

var textarea;
var doc;
var handler;
var dnd;
var files;

function setUp() {
  textarea = new goog.events.EventTarget();
  doc = new goog.events.EventTarget();
  textarea.ownerDocument = doc;
  handler = new goog.events.FileDropHandler(textarea);
  dnd = false;
  files = null;
  goog.events.listen(handler, goog.events.FileDropHandler.EventType.DROP,
      function(e) {
        dnd = true;
        files =
            e.getBrowserEvent().dataTransfer.files;
      });
}

function tearDown() {
  textarea.dispose();
  doc.dispose();
  handler.dispose();
}

function testOneFile() {
  var preventDefault = false;
  var expectedfiles = [{ fileName: 'file1.jpg' }];
  var dt = { types: ['Files'], files : expectedfiles };

  // Assert that default actions are prevented on dragenter.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGENTER,
      dataTransfer : dt
  }));
  assertTrue(preventDefault);
  preventDefault = false;

  // Assert that default actions are prevented on dragover.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGOVER,
      dataTransfer : dt
  }));
  assertTrue(preventDefault);
  preventDefault = false;
  // Assert that the drop effect is set to 'copy'.
  assertEquals('copy', dt.dropEffect);

  // Assert that default actions are prevented on drop.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DROP,
      dataTransfer : dt
  }));
  assertTrue(preventDefault);

  // Assert that DROP has been fired.
  assertTrue(dnd);
  assertEquals(1, files.length);
  assertEquals(expectedfiles[0].fileName, files[0].fileName);
}

function testMultipleFiles() {
  var preventDefault = false;
  var expectedfiles = [{ fileName: 'file1.jpg' }, { fileName: 'file2.jpg' }];
  var dt = { types: ['Files', 'text'], files : expectedfiles };

  // Assert that default actions are prevented on dragenter.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGENTER,
      dataTransfer : dt
  }));
  assertTrue(preventDefault);
  preventDefault = false;

  // Assert that default actions are prevented on dragover.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGOVER,
      dataTransfer : dt
  }));
  assertTrue(preventDefault);
  preventDefault = false;
  // Assert that the drop effect is set to 'copy'.
  assertEquals('copy', dt.dropEffect);

  // Assert that default actions are prevented on drop.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DROP,
      dataTransfer : dt
  }));
  assertTrue(preventDefault);

  // Assert that DROP has been fired.
  assertTrue(dnd);
  assertEquals(2, files.length);
  assertEquals(expectedfiles[0].fileName, files[0].fileName);
  assertEquals(expectedfiles[1].fileName, files[1].fileName);
}

function testNoFiles() {
  var preventDefault = false;
  var dt = { types: ['text'] };

  // Assert that default actions are not prevented on dragenter.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGENTER,
      dataTransfer : dt
  }));
  assertFalse(preventDefault);
  preventDefault = false;

  // Assert that default actions are not prevented on dragover.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGOVER,
      dataTransfer : dt
  }));
  assertFalse(preventDefault);
  preventDefault = false;

  // Assert that default actions are not prevented on drop.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DROP,
      dataTransfer : dt
  }));
  assertFalse(preventDefault);

  // Assert that DROP has not been fired.
  assertFalse(dnd);
  assertNull(files);
}

function testDragEnter() {
  var preventDefault = false;

  // Assert that default actions are prevented on dragenter.
  // In Chrome the dragenter event has an empty file list and the types is
  // set to 'Files'.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGENTER,
      dataTransfer : { types: ['Files'], files : [] }
  }));
  assertTrue(preventDefault);
  preventDefault = false;

  // Assert that default actions are prevented on dragenter.
  // In Safari 4 the dragenter event has an empty file list and the types is
  // set to 'public.file-url'.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGENTER,
      dataTransfer : { types: ['public.file-url'], files : [] }
  }));
  assertTrue(preventDefault);
  preventDefault = false;

  // Assert that default actions are not prevented on dragenter
  // when the drag contains no files.
  textarea.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGENTER,
      dataTransfer : { types: ['text'], files : [] }
  }));
  assertFalse(preventDefault);
}

function testPreventDropOutside() {
  var preventDefault = false;
  var dt = { types: ['Files'], files : [{ fileName: 'file1.jpg' }] };

  // Assert that default actions are not prevented on dragenter on the
  // document outside the text area.
  doc.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGENTER,
      dataTransfer : dt
  }));
  assertFalse(preventDefault);
  preventDefault = false;

  // Assert that default actions are not prevented on dragover on the
  // document outside the text area.
  doc.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGOVER,
      dataTransfer : dt
  }));
  assertFalse(preventDefault);
  preventDefault = false;

  handler.dispose();
  // Create a new FileDropHandler that prevents drops outside the text area.
  handler = new goog.events.FileDropHandler(textarea, true);

  // Assert that default actions are now prevented on dragenter on the
  // document outside the text area.
  doc.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGENTER,
      dataTransfer : dt
  }));
  assertTrue(preventDefault);
  preventDefault = false;

  // Assert that default actions are now prevented on dragover on the
  // document outside the text area.
  doc.dispatchEvent(new goog.events.BrowserEvent({
      preventDefault : function() { preventDefault = true; },
      type : goog.events.EventType.DRAGOVER,
      dataTransfer : dt
  }));
  assertTrue(preventDefault);
  preventDefault = false;
  // Assert also that the drop effect is set to 'none'.
  assertEquals('none', dt.dropEffect);
}

</script>
</body>
</html>
